using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Blabber.Data;
using System.Data;
using System.IO;
using System.Runtime.InteropServices;

namespace Blabber.Client
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>

    public partial class WindowMain : System.Windows.Window
    {
        CommunicationData _communicator;
        Dictionary<string, WindowChat> _chatWindows;
        DataSetModel _model;

        WindowChat _communityWindow;
        
        public WindowMain()
        {
            InitializeComponent();

            Blabber.Client.Properties.Settings.Default.Reload();

            this.Left = Blabber.Client.Properties.Settings.Default.MainWindowLocation.X;
            this.Top = Blabber.Client.Properties.Settings.Default.MainWindowLocation.Y;

            this.Height = Blabber.Client.Properties.Settings.Default.MainWindowSize.Height;
            this.Width = Blabber.Client.Properties.Settings.Default.MainWindowSize.Width;

            this.Loaded += new RoutedEventHandler(WindowMain_Loaded);
            
        }

        void WindowMain_Loaded(object sender, RoutedEventArgs e)
        {
            _model = new DataSetModel();
            if (File.Exists("blabberdata.xml"))
            {
                _model.ReadXml("blabberdata.xml");
            }
            else
            {
                settingsOperation();
            }

            if (_model.Status.Rows.Count == 0)
                setDefaultStatus();

            _communicator = new CommunicationData(this);
            _communicator.Model = _model;
            _communicator.MessageReceivedEvent += new EventHandler(_communicator_MessageReceivedEvent);

            rosterListBox.DataContext = _communicator.RosterView;
            comboBoxStatus.DataContext = _model.Status;

            _chatWindows = new Dictionary<string, WindowChat>();

            menuItemSignInOut.Header = "Sign In";
        }

        private void setDefaultStatus()
        {
            Blabber.Data.DataSetModel.StatusRow row;

            row = _model.Status.NewStatusRow();
            row.Name = "Available";
            row.Show = 1;
            row.IsFactory = true;
            _model.Status.AddStatusRow(row);

            row = _model.Status.NewStatusRow();
            row.Name = "Busy";
            row.Show = 2;
            row.IsFactory = true;
            _model.Status.AddStatusRow(row);

            row = _model.Status.NewStatusRow();
            row.Name = "Away";
            row.Show = 0;
            row.IsFactory = true;
            _model.Status.AddStatusRow(row);
        }

        private void createCommunityWindow()
        {
            _communityWindow = new WindowChat();
            _communityWindow.Communicator = _communicator;
            _communityWindow.Jid = null;
            _communityWindow.Closed += new EventHandler(_communityWindow_Closed);
            _communityWindow.MessageItemDoubleClick += new EventHandler(_communityWindow_MessageItemDoubleClick);
        }

        void _communityWindow_MessageItemDoubleClick(object sender, EventArgs e)
        {
            Blabber.Data.DataSetMessage.MessageRow row = (sender as Blabber.Data.DataSetMessage.MessageRow);
            if (null != row)
            {
                if (_chatWindows.ContainsKey(row.From))
                {
                    _chatWindows[row.From].PostMessage(row.Body, row.From, row.To, row.MessageTime);
                }
                else
                {
                    WindowChat chat = new WindowChat();
                    chat.Communicator = _communicator;

                    chat.Jid = _communicator.RosterDictionary[row.From];
                    
                    chat.Closed += new EventHandler(chat_Closed);

                    _chatWindows.Add(row.From, chat);

                    chat.PostMessage(row.Body, row.From, row.To, row.MessageTime);
                }
            }
        }

        void _communityWindow_Closed(object sender, EventArgs e)
        {
            _communityWindow = null;
        }
        
        [DllImport("user32.dll")] public static extern bool MessageBeep( int beep );  

        void _communicator_MessageReceivedEvent(object sender, EventArgs e)
        {
            agsXMPP.protocol.client.Message msg = (sender as agsXMPP.protocol.client.Message);

            if (msg.Type == agsXMPP.protocol.client.MessageType.chat)
            {
                if (_chatWindows.ContainsKey(msg.From.Bare.ToLower()))
                {
                    _chatWindows[msg.From.Bare].PostMessage(msg.Body, msg.From.Bare, msg.To.Bare, DateTime.Now);
                }
                else
                {
                    if (null == _communityWindow)
                    {
                        WindowChat chat = new WindowChat();
                        chat.Communicator = _communicator;
                        chat.Jid = msg.From;
                        chat.PostMessage(msg.Body, msg.From.Bare, msg.To.Bare, DateTime.Now);
                        chat.Closed += new EventHandler(chat_Closed);

                        _chatWindows.Add(msg.From.Bare.ToLower(), chat);
                    }
                    else
                    {
                        _communityWindow.PostMessage(msg.Body, msg.From.Bare, msg.To.Bare, DateTime.Now);
                    }
                }
            }
            else
            {
                if (null != _communityWindow)
                    _communityWindow.PostMessage(msg.Body, msg.From.Bare, msg.To.Bare, DateTime.Now);
            }
        }

        void chat_Closed(object sender, EventArgs e)
        {
            WindowChat chat = (sender as WindowChat);
            _chatWindows.Remove(chat.Jid.Bare);
        }

        #region UI Events

        public void OnWindowClosed(object sender, EventArgs e)
        {
            _communicator.Close();

            Blabber.Client.Properties.Settings.Default.MainWindowLocation = new System.Drawing.Point((int)this.Left, (int)this.Top);
            Blabber.Client.Properties.Settings.Default.MainWindowSize = new System.Drawing.Size((int)this.Width, (int)this.Height);

            Blabber.Client.Properties.Settings.Default.Save();

            _model.WriteXml("blabberdata.xml");
        }

        #endregion

        private void Connect()
        {
            _communicator.Open();
            menuItemSignInOut.Header = "Sign Out";
        }

        private void Disconnect()
        {
            _communicator.Close();
            menuItemSignInOut.Header = "Sign In";
        }

        private void rosterListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListBox listView = (sender as ListBox);
            if (listView.SelectedItem is DataRowView)
            {
                DataRowView row = listView.SelectedItem as DataRowView;
                if (null != row)
                {
                    if (_chatWindows.ContainsKey(row["JID"].ToString().ToLower()))
                    {
                        _chatWindows[row["JID"].ToString()].Show();
                    }
                    else
                    {
                        if (_communicator.RosterDictionary.ContainsKey(row["JID"] as string))
                        {
                            WindowChat chat = new WindowChat();
                            chat.Communicator = _communicator;
                            chat.Jid = _communicator.RosterDictionary[row["JID"].ToString()];
                            chat.Closed += new EventHandler(chat_Closed);

                            _chatWindows.Add(row["JID"].ToString().ToLower(), chat);

                            chat.Show();
                        }
                    }
                }
            }
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            settingsOperation();
        }

        private void settingsOperation()
        {
            WindowSettings settings = new WindowSettings();
            settings.Connections = _model.Connection;

            settings.ShowDialog();

            if ((null != _communicator) && (_communicator.Connected))
            {
                Disconnect();
                Connect();
            }
        }

        private void MenuItemSignOut_Click(object sender, RoutedEventArgs e)
        {
            if (_communicator.Connected)
                Disconnect();
            else
                Connect();
        }

        private void Community_Click(object sender, RoutedEventArgs e)
        {
            if (_communityWindow == null)
            {
                createCommunityWindow();
                _communityWindow.Show();
            }
            else
                _communityWindow.Focus();
        }

        private void statusChangedEvent(object sender, SelectionChangedEventArgs e)
        {
            DataRowView view = (e.AddedItems[0] as DataRowView);
            Blabber.Data.DataSetModel.StatusRow row = view.Row as Blabber.Data.DataSetModel.StatusRow;

            _communicator.SetStatus(row.Name, row.Show);
        }

    }
}